﻿using light.http.server;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


static class LocalExt_File
{
    public static string WorkingPath;
    public static string HTMLPath;
    static UInt32 GetUnixTime(DateTime time)
    {
        return (uint)DateTimeOffset.FromFileTime(time.ToFileTime()).ToUnixTimeSeconds();
    }
    public async static Task onFileExt_GetRoots(HttpContext context)
    {

        context.Response.StatusCode = 200;
        var json = new JObject();
        var logics = new JArray();
        foreach (var d in System.Environment.GetLogicalDrives())
        {
            logics.Add(d);
        }
        json["logic"] = logics;

        var specials = new JObject();
        {
            specials["MyDocuments"] = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            specials["MyMusic"] = System.Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
            specials["MyPictures"] = System.Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            specials["MyVideos"] = System.Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);
            specials["HtmlPath"] = HTMLPath;
            specials["WorkingPath"] = WorkingPath;
        }
        json["special"] = specials;
       
        json["state"] = "ok";
        await context.Response.WriteAsync(json.ToString());
    }
    //done
    public async static Task onFileExt_Dir_Info(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;

            var path = context.Request.Query["path"].ToString();
            var b = System.IO.Directory.Exists(path);
            if (!b)
            {
                json["exists"] = false;
                json["state"] = "ok";
            }
            else
            {
                var dir = new System.IO.DirectoryInfo(path);
                json["exists"] = true;
                json["Name"] = dir.Name;
                json["FullName"] = dir.FullName;
                json["CreationTime"] = GetUnixTime(dir.CreationTime);
                json["LastWriteTime"] = GetUnixTime(dir.LastWriteTime);
                bool hide = (dir.Attributes & System.IO.FileAttributes.Hidden) > 0;
                bool sys = (dir.Attributes & System.IO.FileAttributes.System) > 0;
                bool _readonly = (dir.Attributes & System.IO.FileAttributes.ReadOnly) > 0;
                json["Hidden"] = hide;
                json["System"] = sys;
                json["ReadOnly"] = _readonly;
                json["state"] = "ok";
            }

            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_Dir_Create(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;

            var path = context.Request.Query["path"].ToString();
            var info = System.IO.Directory.CreateDirectory(path);
            json["info"] = info.Name;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_Dir_Delete(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;

            var path = context.Request.Query["path"].ToString();
            System.IO.Directory.Delete(path);

            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_Dir_List(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;


            var bpath = context.Request.Query.TryGetValue("path", out var path);
            var brecursion = context.Request.Query.TryGetValue("recursion", out var recursion);
            var bpattern = context.Request.Query.TryGetValue("pattern", out var pattern);

            if (!bpath)
                throw new Exception("缺少path参数");
            var strpattern = "*.*";
            if (bpattern)
            {
                strpattern = pattern;
            }
            System.IO.SearchOption op = System.IO.SearchOption.TopDirectoryOnly;
            if (brecursion)
            {
                if (recursion == "1" || recursion.ToString().ToLower() == "true")
                {
                    op = System.IO.SearchOption.AllDirectories;
                }
            }
            var dirs = System.IO.Directory.GetDirectories(path, strpattern, op);
            var files = System.IO.Directory.GetFiles(path, strpattern, op);
            var jsondirs = new JArray();
            foreach (var s in dirs)
            {
                jsondirs.Add(s);
            }
            var jsonfiles = new JArray();
            foreach (var s in files)
            {
                jsonfiles.Add(s);
            }
            json["dirs"] = jsondirs;
            json["files"] = jsonfiles;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_File_Info(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;

            var file = context.Request.Query["path"].ToString();
            var b = System.IO.File.Exists(file);
            if (!b)
            {
                json["exists"] = false;
                json["state"] = "ok";
            }
            else
            {
                var _fileinfo = new System.IO.FileInfo(file);
                json["exists"] = true;
                json["Name"] = _fileinfo.Name;
                json["FullName"] = _fileinfo.FullName;
                json["Length"] = _fileinfo.Length;
                json["CreationTime"] = GetUnixTime(_fileinfo.CreationTime);
                json["LastWriteTime"] = GetUnixTime(_fileinfo.LastWriteTime);
                bool hide = (_fileinfo.Attributes & System.IO.FileAttributes.Hidden) > 0;
                bool sys = (_fileinfo.Attributes & System.IO.FileAttributes.System) > 0;
                bool _readonly = (_fileinfo.Attributes & System.IO.FileAttributes.ReadOnly) > 0;
                json["Hidden"] = hide;
                json["System"] = sys;
                json["ReadOnly"] = _readonly;
                json["state"] = "ok";
            }

            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_File_Read(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            if (context.Request.Method == "Head")
            {
                context.Response.StatusCode = 200;
                await context.Response.WriteAsync("cool");
            }

            var form = await FormData.FromRequest(context.Request);


            context.Response.StatusCode = 200;

            var bpath = context.Request.Query.TryGetValue("path", out var p_path);
            var format = context.Request.Query.TryGetValue("format", out var p_format);
            if (!bpath)
                throw new Exception("缺失参数:path");
            bool istext = false;
            if (format)
            {
                var strformat = p_format.ToString().ToLower();
                if (strformat == "text" || strformat == "txt")
                    istext = true;

            }


            var binary = System.IO.File.ReadAllBytes(p_path);
            await context.Response.Body.WriteAsync(binary);

        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    public async static Task onFileExt_File_Write(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            if (context.Request.Method == "Head")
            {
                context.Response.StatusCode = 200;
                await context.Response.WriteAsync("cool");
            }
            if (context.Request.Method != "POST")
            {
                throw new Exception("suport post only");
            }
            var form = await FormData.FromRequest(context.Request);

            context.Response.StatusCode = 200;


            var bpath = context.Request.Query.TryGetValue("path", out var p_path);

            string filename = p_path;
            byte[] buf = null;
            if (context.Request.ContentType != null && context.Request.ContentType.Contains("multipart/form-data"))
            {

                if (form == null || form.mapFiles == null || form.mapFiles.Count == 0)
                {
                    throw new Exception("用multipart方式提交，必须是文件形式");
                }
                buf = form.mapFiles.First().Value;
            }
            else
            {
                //整体，是不是字符串不重要，反正囫囵一顿写
                if (context.Request.ContentType == "text/plain;charset=UTF-8")
                {

                }

                buf = new byte[(int)context.Request.ContentLength];
                int seek = 0;
                while (seek < buf.Length)
                {
                    int readlen = await context.Request.Body.ReadAsync(buf, seek, buf.Length - seek);
                    seek += readlen;
                }
            }


            System.IO.File.WriteAllBytes(filename, buf);
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_File_Delete(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;

            var path = context.Request.Query["path"].ToString();
            System.IO.File.Delete(path);

            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
    //done
    public async static Task onFileExt_File_Copy(HttpContext context)
    {

        var json = new JObject();
        if (context.Request.QueryString.HasValue == false)
        {
            context.Response.StatusCode = 400;
            json["msg"] = "param error";
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

        try
        {
            context.Response.StatusCode = 200;

            var from = context.Request.Query["from"].ToString();
            var to = context.Request.Query["to"].ToString();
            System.IO.File.Copy(from, to, true);

            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
        }
        catch (Exception err)
        {
            context.Response.StatusCode = 400;
            json["msg"] = err.Message;
            json["state"] = "ok";
            await context.Response.WriteAsync(json.ToString());
            return;
        }

    }
}

